UXarray logo

Data Visualization

In this tutorial, you’ll learn about:

  • Plotting data variables that reside on unstructured grid elements (nodes, edges, faces)

  • Polygon and Point plotting routines


Introduction

The previous section showcased how to visualize the geometry of unstructured grids using the Grid class. In this section, we will now visualize data variables that reside on unstructured elements.

Data Mapping

Data variables that exist on unstructured grids often are mapped to different elements, such as nodes, edges, or faces, which impacts the choice of visualization method.

import uxarray as ux
grid_path = "../../meshfiles/oQU480.grid.nc"
data_path = "../../meshfiles/oQU480.data.nc"

uxds = ux.open_dataset(grid_path, data_path)
uxds["bottomDepth"]
<xarray.UxDataArray 'bottomDepth' (n_face: 1791)> Size: 14kB
[1791 values with dtype=float64]
Dimensions without coordinates: n_face

Our data variable above, bottomDepth, has a final dimension of n_face, meaning that it is mapped to the faces of our grid.

Plotting Accessor

All plotting methods are accessed through the UxDataArray.plot accessor.

uxds["bottomDepth"].plot()

Polygons

The default plotting method for face-centered data variables is a raster polygon plot. Each face in the unstructured grid is represented as a polygon, shaded with its corresponding data.

uxds["bottomDepth"].plot.polygons()

Raster vs Vector Polygons

By default, rasterization (i.e. setting rasterize=True) is performed on the polygons to more efficiently render the grid. For higher-resolution grids, it is suggested to keep rasterize=True, since rendering each polygon directly takes a significant amount of time.

When rasterize=False, the vector polygons are rendered.

uxds["bottomDepth"].plot.polygons(rasterize=False)

The defining characteristic of vector polygon plots is that there is no loss of data fidelity (i.e. the accuracy and/or quality) when zooming in.

Zooming into a region of our grid highlights this, which can be seen in the plot below.

(
    uxds["bottomDepth"].plot.polygons(
        rasterize=False, xlim=(-20, 0), ylim=(-5, 5), title="Vector Polygons"
    )
    + uxds["bottomDepth"].plot.polygons(
        rasterize=True, xlim=(-20, 0), ylim=(-5, 5), title="Raster Polygons"
    )
).cols(1)

Handling Periodic Elements

Antimeridian Example

When attempting to visualize unstructured grids that reside on a sphere, it is necessary to consider the behavior of faces near the antimeridian. Faces that wrap around the antimeridian need to be processed to properly produce a 2D Visualization.

UXarray provides the periodic_elements parameter for polygon plotting routines, which gives the user control over how to handle faces that cross the antimeridian.

  • periodic_elements='exclude: Default value, faces are masked and not included in the visualization

  • periodic_elements='split': Faces are split along the antimeridian

It is suggested to keep periodic_elements='exclude' for the best performance.

(
    uxds["bottomDepth"].plot.polygons(
        periodic_elements="exclude", title="periodic_elements='exclude'"
    )
    + uxds["bottomDepth"].plot.polygons(
        periodic_elements="split", title="periodic_elements='split'"
    )
).cols(1)

Polygon Plots for Node/Edge Data

Polygon plotting is only supported for face-centered data variables, since each polygon must be shaded by a single value. If you are working with node or edge centered data, you must someone map that data to the faces.

One simple approach would be to perform a topological average of the node/edge centered data and store the result at the faces.

grid_path = "../../meshfiles/hex.grid.nc"
data_path = "../../meshfiles/hex.node.data.nc"

uxds_node_centered = ux.open_dataset(grid_path, data_path)
uxds_node_centered["random_data_node"].topological_mean(destination="face").plot()

In the example above, the average of the nodes that surround each face is computed and stored on the face, which allows the data to be visualuzed as polygons.

Points

Data can also be visualized as points, with the appropriate coordinates colored according to the node, edge, or face data.

Below, we can visualize our face-centered data variable by coloring the face-center coordinates with the corresponding data.

uxds["bottomDepth"].plot.points()

Rasterization

Just like with the polygon plots, we can also rasterize our points by setting rasterize=True.

uxds["bottomDepth"].plot.points(rasterize=True)

For coarse resolutions, such as the one used in this example, the result looks significantly worse than the polygon plots. However, rasterized point plots can be extremely useful for visualize high-resolution grids quickly, which is discussed in the Visualizng High-Resolution Grids section.